#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017, Fabian Greif
# Copyright (c) 2017-2018, Niklas Hauser
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

def init(module):
    module.name = ":platform:core"
    module.description = FileReader("module.md")

def prepare(module, options):
    if not options[":target"].has_driver("core:avr*"):
        return False

    module.add_option(
        NumericOption(
            name="f_cpu",
            description="CPU clock frequency",
            minimum=1,
            maximum="32M"))

    module.depends(":architecture:interrupt", ":stdc++")
    return True

def build(env):
    target = env[":target"]
    is_xmega = "xmega" in target.get_driver("core")["type"]

    env.outbasepath = "modm/link"
    env.copy("linkerscript.ld")
    env.collect(":build:linkflags", "-L{project_source_dir}",
                "-T{}".format(env.relcwdoutpath("modm/link/linkerscript.ld")))

    env.substitutions = {
        "target": target.identifier,
        "core": target.get_driver("core")["type"],
        "f_cpu": env["f_cpu"],
        "shift": int(4e9/env["f_cpu"]).bit_length(),
    }
    env.outbasepath = "modm/src/modm/platform/core"

    env.copy("main.hpp")

    # dealing with runtime assertions
    if env.has_module(":architecture:assert"):
        env.template("../cortex/assert.cpp.in", "assert.cpp")
        env.template("../cortex/assert_impl.hpp.in", "assert_impl.hpp")

    if env.has_module(":architecture:atomic"):
        env.copy("atomic_lock_impl.hpp")

    if env.has_module(":architecture:unaligned"):
        env.copy("unaligned_impl.hpp")

    if env.has_module(":architecture:accessor"):
        env.copy("flash_reader_impl.hpp")

    if env.has_module(":architecture:delay"):
        env.template("delay_impl.hpp.in")

    env.template("interrupts.hpp.in")

    if is_xmega:
        env.copy("utils.hpp")
        env.copy("utils.cpp")

    # avr-gcc only accepts certain device strings for its -mmcu flag
    # See https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html
    mmcu = target.partname.split("-")[0]
    for suffix in {"v", "f", "l", "rc"}:
        mmcu = mmcu[:-2] + mmcu[-2:].replace(suffix, "")
    env.collect(":build:archflags","-mmcu={}".format(mmcu))
    env.collect(":build:cppdefines", "F_CPU={}".format(env["f_cpu"]))
    env.collect(":build:ccflags", "--param=min-pagesize=0")


